package com.lupan.zookeeper;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.TreeCache;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
import org.apache.curator.framework.recipes.cache.TreeCacheListener;
import org.apache.curator.retry.RetryNTimes;
import org.apache.curator.utils.CloseableUtils;
import org.apache.curator.utils.ZKPaths;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * 说明：zookeeper学习
 *
 * @author lupan
 * @version 2017/3/14 10:58
 */
public class ZookeeperStudy {

    private static Logger logger = LoggerFactory.getLogger(ZookeeperStudy.class);

    private CuratorFramework client;

    private TreeCache treeCache;

    public ZookeeperStudy() {
        client = CuratorFrameworkFactory.builder()
                .namespace("myApp")
                .retryPolicy(new RetryNTimes(Integer.MAX_VALUE, 1000))
                .connectString("tspuathadoopslave01.uat:2181,tspuathadoopslave02.uat,tspuathadoopmaster02.uat:2181")
                .build();
        client.start();
    }

    /**
     * 基础api操作
     *
     * @throws Exception
     */
    public void baseApi() throws Exception {


        List<String> children2 = client.getChildren().forPath("/ecuSync");
        ZKPaths.deleteChildren(client.getZookeeperClient().getZooKeeper(),"/myApp/ecuSync",true);
//        for(String childPath:children2){
//            client.delete().forPath(ZKPaths.PATH_SEPARATOR+childPath);
//        }

        client.delete().forPath("/ecuSync");

        //创建节点
        String path = client.create().forPath("/ecuSync");

        //创建子节点
        client.create().forPath(ZKPaths.makePath("ecuSync", "vin1_ecu1"), "ecu1".getBytes());
        client.create().forPath("/ecuSync/vin1_ecu2", "ecu2".getBytes());
        client.create().forPath("/ecuSync/vin1_ecu3", "ecu3".getBytes());

        //读取节点数据
        byte[] data = client.getData().forPath("/ecuSync/vin1_ecu1");

        //更新节点数据
        client.setData().forPath("/ecuSync/vin1_ecu1", "ecu1_new".getBytes());
        byte[] data2 = client.getData().forPath("/ecuSync/vin1_ecu1");

        //检查节点是否存在
        Stat isExists = client.checkExists().forPath("/ecuSync");

        //获取子节点列表
        List<String> children = client.getChildren().forPath("/ecuSync");

        //删除节点
        client.delete().forPath("/ecuSync/vin1_ecu3");
        Stat isExists2 = client.checkExists().forPath("/ecuSync/vin1_ecu3");

        client.delete().forPath("/ecuSync");

        //关闭连接
        CloseableUtils.closeQuietly(client);
    }

    /**
     * 事件监听
     */
    public void evenListener() throws Exception {

//        String path = client.create().forPath("/ecuSync");
        Stat isExists = client.checkExists().forPath("/ecuSync");

        List<String> children = client.getChildren().forPath("/ecuSync");

        treeCache = new TreeCache(client, "/ecuSync");

        treeCache.getListenable().addListener(new TreeCacheListener() {
            @Override
            public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {
                //获取事件类型
                TreeCacheEvent.Type eventType = event.getType();
                //获取发生事件的节点
                ZKPaths.PathAndNode pathAndNode = ZKPaths.getPathAndNode(event.getData().getPath());

                logger.info("事件类型：{},发生事件的路径：{},发生事件的节点：{}", eventType.toString(),pathAndNode.getPath(),pathAndNode.getNode());
            }
        });

        treeCache.start();

        Thread.sleep(2000);

        client.create().forPath("/ecuSync/vin1", "ecu1".getBytes());
//        client.delete().forPath("/ecuSync/vin1");

        client.create().forPath("/ecuSync/vin1/ecu1", "ecu1".getBytes());
        client.delete().forPath("/ecuSync/vin1/ecu1");

        //关闭连接
        CloseableUtils.closeQuietly(client);
    }

    public CuratorFramework getClient() {
        return client;
    }

    public void setClient(CuratorFramework client) {
        this.client = client;
    }
}
